package com.frame.ar.util;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.transform.TransformerException;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;


/*******************************************
 * 作用描述：编码工具类
 *******************************************
 * @author LRC
 * @createDate 2015-9-11
 * @version v1.0 
 * @updateRecord 格式：时间，作者，修改说明
 *******************************************
 * 
 */
public class Coder {
	/**
	 * 加密因子
	 */
	private static char SOLD = '@'; 
	
	/*******************************************
	 * 功能描述：可逆的字符编码操作
	 *******************************************
	 * @createDate 2015-9-11 by LRC
	 * @param data 
	 * @return 
	 * @updateRecord 格式：时间，作者，修改说明
	 *******************************************
	 * 
	 */
	public static String rEncode(String data){
		if(data==null||data.length()==0){
			return null;
		}
		char[] _data = data.toCharArray();
		//自定义加密
		_data = encrypt(_data, SOLD);
		//获取统一编码对象
		BASE64Encoder encoder = new BASE64Encoder();
		return encoder.encodeBuffer(new String(_data).getBytes());
	}
	
	/**
	 * 编码路径，解密
	 * @param path
	 * @return
	 * @throws IOException 
	 */
	public static String rDecode(String data) throws IOException{
		if(data==null||data.length()==0){
			return null;
		}
		BASE64Decoder decoder = new BASE64Decoder();
		
		byte[] _data =  decoder.decodeBuffer(data);
		
		char[] paths = new String(_data).toCharArray();
		//自定义加密
		paths = decrypt(paths, SOLD);
		
		return new String(paths);
	}
	
	/**
	 * @updateTeim 2015年5月22日下午10:40:32
	 * @description 自定义编码方法
	 * @param chs 被编码的字符串
	 * @param sold 编码因子
	 * @return 编码后的字符数组
	 */
	private static char[] encrypt(char[] chs, char sold){
		if(chs==null||chs.length==0)return chs;
		char[] encs = new char[chs.length];
		for(int i=0; i<chs.length; i++){
			encs[i] = (char) (chs[i] + sold - i%sold);
		}
		return encs;
	}
	
	/**
	 * @updateTeim 2015年5月22日下午10:41:10
	 * @description 自定义解码方法
	 * @param chs 被解码的字符数组
	 * @param sold 编码时的因子
	 * @return 解码后的字符数组
	 */
	private static char[] decrypt(char[] chs, char sold){
		if(chs==null||chs.length==0)return chs;
		char[] encs = new char[chs.length];
		for(int i=0; i<chs.length; i++){
			encs[i] = (char) (chs[i] - sold + i%sold);
		}
		return encs;
	}
	
	/**
	 * 加密字符串，不可逆
	 * @param path
	 * @return
	 */
	public static String _encoder(String orgstr,String sold){
		if(orgstr==null||orgstr.length()==0){
			return null;
		}
		String _orgstr = sold+orgstr;
		char[] paths = _orgstr.toCharArray();
		//自定义加密
		paths = encrypt(paths, SOLD);
		//获取计算摘要对象
		MessageDigest md = null;
		//获取摘要数据
		byte[] data = null;
		try {
			md = MessageDigest.getInstance("md5");
			data = md.digest(new String(paths).getBytes("utf-8"));
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			return null;
		}catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return null;
		}
		//获取统一编码对象
		BASE64Encoder encoder = new BASE64Encoder();
		return encoder.encode(data);
	}
	
	/**
	 * @updateTeim 2015年5月22日下午10:34:38
	 * @description 使用BASE64进行编码
	 * @param str
	 * @return
	 */
	public static String base64Encode(String orgstr){
		if(orgstr==null||"".equals(orgstr.trim()))return null;
		byte[] data = null;
		try {
			data = orgstr.getBytes("utf-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return null;
		}
		BASE64Encoder encoder = new BASE64Encoder();
		return encoder.encode(data);
	}
	
	/**
	 * @updateTeim 2015年5月22日下午10:37:02
	 * @description base64解码操作
	 * @param code
	 * @return
	 */
	public static String base64Decode(String code){
		if(code==null||"".equals(code.trim()))return null;
		BASE64Decoder decoder = new BASE64Decoder();
		byte[] data = null;
		try {
			data =  decoder.decodeBuffer(code);
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
		try {
			return new String(data,"utf-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return null;
		}
	}
	public static String SHA256Encrypt(String orignal){
		MessageDigest md = null; 
        try { 
            md = MessageDigest.getInstance("SHA-256"); 
        } catch (NoSuchAlgorithmException e) { 
            e.printStackTrace(); 
            return null;
        }
        byte[] byteArray = null;
		try {
			byteArray = orignal.getBytes("UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return null;
		}
        byte[] mdBytes = md.digest(byteArray);
        StringBuffer hexValue = new StringBuffer();
        for (int i = 0; i < mdBytes.length; i++) {
            int val = ((int) mdBytes[i]) & 0xff;
            if (val < 16) {
                hexValue.append("0");
            }
            hexValue.append(Integer.toHexString(val));
        }
        return hexValue.toString();
	}
	public static String MD5Encrypt(String orignal){
		MessageDigest md5 = null; 
        try { 
            md5 = MessageDigest.getInstance("SHA-256"); 
        } catch (NoSuchAlgorithmException e) { 
            e.printStackTrace(); 
            return null;
        }
        byte[] byteArray = null;
		try {
			byteArray = orignal.getBytes("UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return null;
		}
        byte[] md5Bytes = md5.digest(byteArray);
        StringBuffer hexValue = new StringBuffer();
        for (int i = 0; i < md5Bytes.length; i++) {
            int val = ((int) md5Bytes[i]) & 0xff;
            if (val < 16) {
                hexValue.append("0");
            }
            hexValue.append(Integer.toHexString(val));
        }
        return hexValue.toString();
	}
	public static String HmacMD5Encrypt(String key ,String value) throws TransformerException {
		byte[] data = null;
		byte[] keyData = null;
		try {
			data = value.getBytes("utf-8");
			keyData = key.getBytes("US-ASCII");
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
			return null;
		}
		SecretKeySpec sk = new SecretKeySpec(keyData, "HmacMD5");
		Mac mac;
		try {
			mac = Mac.getInstance("HmacMD5");
			mac.init(sk);
			byte[] rData = mac.doFinal(data);
			System.out.println(Arrays.toString(rData));
			return new String(rData,"utf-8");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	public static void main(String[] args) {
		String appId="wx5855e386ce3ad861";
		String appsecret="680152139595906fee537085a83f18b4";
		String token = "dmiswxBass";
		
		System.out.println("appId="+rEncode("wx5855e386ce3ad861"));
		System.out.println("appsecret="+rEncode("680152139595906fee537085a83f18b4"));
		System.out.println("token="+rEncode("dmiswxBass"));
	}
}
